﻿using System.Web.Mvc;
using System.Web;
using System.Web.Routing;
using System.Globalization;
using System.Threading;
using System;
using System.Web.Security;
using System.Linq;

namespace WebPattern.Core.MultiCulture
{
    public class MultiCultureMvcRouteHandler : MvcRouteHandler
    {        
        protected override IHttpHandler GetHttpHandler(RequestContext requestContext)
        {
            // Error
            if (requestContext.RouteData.Values["controller"].ToString() == "Error") 
                return base.GetHttpHandler(requestContext);          

            string cultureCode = requestContext.RouteData.Values["culture"].ToString();
            FormsAuthentication.Initialize();
            string loginUrl = FormsAuthentication.LoginUrl;

            #region URL Culutre = default or is loginUrl from web.config
            if (  cultureCode == MultiCultureHelper.CultureCodeDic.Where(p=>p.Key== CultureKey.Default).First().Value || (requestContext.HttpContext.Request.Url.LocalPath == loginUrl && !MultiCultureHelper.CultureCodeDic.ContainsValue(cultureCode)))
            {
                // check coockies
                if (requestContext.HttpContext.Request.Cookies["CulureCookies"] != null)
                {
                    // read cookie
                    requestContext.RouteData.Values["culture"] = cultureCode = requestContext.HttpContext.Request.Cookies["CulureCookies"].Value;
                }
                else
                {
                    // set browser culture
                    requestContext.RouteData.Values["culture"] = cultureCode = Thread.CurrentThread.CurrentCulture.Name;
                }

                if (requestContext.HttpContext.Request.Url.LocalPath == loginUrl)
                {
                    // VERY IMPORTENT to use requestContext.HttpContext.Request.Url.PathAndQuery for redirecting - because it contain returnUrl.
                    requestContext.HttpContext.Response.Redirect("/" + cultureCode + requestContext.HttpContext.Request.Url.PathAndQuery);
                }
            }
            #endregion

            #region Check if culture is in ours Culture collection
            if (string.IsNullOrWhiteSpace(cultureCode) || !MultiCultureHelper.CultureCodeDic.ContainsValue(cultureCode))
            {
                // TO DO: log error

                if (requestContext.HttpContext.Request.Cookies["CulureCookies"] != null)
                {
                    // read cookie
                    cultureCode = requestContext.HttpContext.Request.Cookies["CulureCookies"].Value;
                    if (!MultiCultureHelper.CultureCodeDic.ContainsValue(cultureCode)) goto THROWEX;

                    CultureInfo ci = new CultureInfo(cultureCode);
                    Thread.CurrentThread.CurrentUICulture = ci;
                    Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture(ci.Name);
                }

            THROWEX:
                throw new HttpException(404,
                              String.Format(
                                  CultureInfo.CurrentUICulture,
                                  "Culture:\"" + requestContext.RouteData.Values["culture"].ToString() + "\" not suported.",
                                  requestContext.HttpContext.Request.Path));
            }
            #endregion

            CultureInfo ci2 = new CultureInfo(cultureCode);
            Thread.CurrentThread.CurrentUICulture = ci2;
            Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture(ci2.Name);

            #region Write culture in cookie if is not equal
            if (requestContext.HttpContext.Request.Cookies["CulureCookies"] != null)
            {
                if (requestContext.HttpContext.Request.Cookies["CulureCookies"].Value != ci2.Name)
                {
                    HttpCookie aCookie = new HttpCookie("CulureCookies");
                    requestContext.RouteData.Values["culture"] = cultureCode = aCookie.Value = ci2.Name;
                    aCookie.Expires = DateTime.Now.AddYears(50);
                    requestContext.HttpContext.Response.Cookies.Add(aCookie);
                }
            }
            else
            {
                HttpCookie aCookie = new HttpCookie("CulureCookies");
                requestContext.RouteData.Values["culture"] = cultureCode = aCookie.Value = ci2.Name;
                aCookie.Expires = DateTime.Now.AddYears(50);
                requestContext.HttpContext.Response.Cookies.Add(aCookie);
            }
            #endregion

            return base.GetHttpHandler(requestContext);
        }
    }
}
